import React, {useEffect, useState} from 'react'
import {connectComponent} from '../../../store/utils'
import {Loading} from '../../../ui/loading/Loading'
import {UserDto} from '../../../../api/UserDto'
import {CONSTANTS} from '../../../../constants'
import {apiPost} from '../../../api'
import {LSKeys, LSMethods} from '../../../storage'
import InputSelectVertical from '../../../ui/form/inputSelect/InputSelectVertical'
import InputSelectOption from '../../../ui/form/inputSelect/InputSelectOption'
import {Tag} from '../../../ui/tag/Tag'
import Divider from '../../../ui/common/Divider'
import {Button} from '../../../ui/button/Button'
import {createToast} from '../../../ui/toast/toast'

export interface IMedItem {
  name: string
  id: string
}

export interface IMedMap {
  allergens: IMedItem[]
  vitamins: IMedItem[]
  diet_tables: IMedItem[]
}

export interface ProfileContainerProps {
  user: UserDto
}

const ProfileContainer: React.FC<ProfileContainerProps> = ({user}): React.ReactElement => {
  const [medMap, setMedMap] = useState<IMedMap>(undefined)
  const [myMedMap, setMyMedMap] = useState<IMedMap>(undefined)

  const loadMedMap = async (): Promise<void> => {
    const url = CONSTANTS.apiUrl + '/meds/list'
    const res = await apiPost(url, {types: ['allergens', 'vitamins', 'diet_tables']}, {})
    const loadedMedMap: IMedMap = res.result
    setMedMap({...loadedMedMap})
  }

  useEffect(() => {
    loadMedMap()
  }, [])

  const loadMyMedMap = async (): Promise<void> => {
    const token = LSMethods.getStorageData(LSKeys.TOKEN)
    const url = CONSTANTS.apiUrl + '/profile/meds/read'
    const res = await apiPost(url, {token: token}, {})
    const loadedMyMedMap: IMedMap = res.result
    setMyMedMap({...loadedMyMedMap})
  }

  useEffect(() => {
    if (user) {
      loadMyMedMap()
    }
  }, [user])

  const writeMed = async (): Promise<void> => {
    const token = LSMethods.getStorageData(LSKeys.TOKEN)

    let writMedMap: {
      allergens: string[]
      vitamins: string[]
      diet_tables: string[]
    } = {
      allergens: (myMedMap.allergens || []).map((a) => a.id) || [],
      vitamins: (myMedMap.vitamins || []).map((v) => v.id) || [],
      diet_tables: (myMedMap.diet_tables || []).map((d) => d.id) || [],
    }

    const res = await apiPost(
      CONSTANTS.apiUrl + '/profile/meds/write',
      {
        token: token,
        meds: writMedMap,
      },
      {},
    )
    if (res.success) {
      createToast('Сохранено', {
        type: 'success',
      })
    }
  }

  const renderAllergen = (): React.ReactNode => {
    let allergenOptions: InputSelectOption[] = (medMap?.allergens || []).map((mm) => {
      return {
        value: mm.id,
        label: mm.name,
      }
    })
    let tagItems: React.ReactNode[] = []

    for (let i = 0; i < (myMedMap?.allergens || []).length; i++) {
      const allergen = myMedMap?.allergens[i]
      tagItems.push(
        <Tag
          key={allergen.id}
          tagText={allergen.name}
          size={'xs'}
          color={'gray-300'}
          className={'mb-x4 mr-x2 ml-x2'}
          onClose={(): void => {
            let newMyMedMap = {...myMedMap}
            myMedMap.allergens.splice(i, 1)
            setMyMedMap({...newMyMedMap})
          }}
        />,
      )
    }

    return (
      <div className={'d-flex flex-column align-items-start'}>
        <p className={'sec-subtitle1 mb-x4'}>Aллергены</p>
        <div
          className={
            'd-flex flex-row flex-wrap sec-subtitle2 ' + (tagItems?.length > 0 ? 'mb-0' : 'mb-x4')
          }>
          Выбранные: {tagItems?.length > 0 ? tagItems : 'пусто'}
        </div>
        <InputSelectVertical
          id={'allergens'}
          size={'sm'}
          options={allergenOptions}
          label={'Аллергены'}
          className={'mb-x6'}
          value={allergenOptions.find((item) => item.value === undefined)}
          onChange={(value: any): void => {
            let newMyMedMap = {...myMedMap}
            let index = newMyMedMap.allergens.findIndex((mmm) => mmm.id === value.value)
            if (index === -1) {
              let itemAllergen = allergenOptions.find((item) => item.value === value.value)
              myMedMap.allergens.push({
                id: itemAllergen.value,
                name: itemAllergen.label,
              })
              setMyMedMap({...newMyMedMap})
            }
          }}
          name={'allergens'}
          isRequired={false}
        />
      </div>
    )
  }

  const renderVitamins = (): React.ReactNode => {
    let vitaminOptions: InputSelectOption[] = (medMap?.vitamins || []).map((mm) => {
      return {
        value: mm.id,
        label: mm.name,
      }
    })
    let tagItems: React.ReactNode[] = []

    for (let i = 0; i < (myMedMap?.vitamins || []).length; i++) {
      const vitamin = myMedMap?.vitamins[i]
      tagItems.push(
        <Tag
          key={vitamin.id}
          tagText={vitamin.name}
          size={'xs'}
          color={'gray-300'}
          className={'mb-x4 mr-x2 ml-x2'}
          onClose={(): void => {
            let newMyMedMap = {...myMedMap}
            myMedMap.vitamins.splice(i, 1)
            setMyMedMap({...newMyMedMap})
          }}
        />,
      )
    }
    return (
      <div className={'d-flex flex-column align-items-start'}>
        <p className={'sec-subtitle1 mb-x4'}>Витамины</p>
        <div
          className={
            'd-flex flex-row flex-wrap sec-subtitle2 ' + (tagItems?.length > 0 ? 'mb-0' : 'mb-x4')
          }>
          Выбранные: {tagItems?.length > 0 ? tagItems : 'пусто'}
        </div>
        <InputSelectVertical
          id={'vitamins'}
          size={'sm'}
          options={vitaminOptions}
          label={'Витамины'}
          className={'mb-x6'}
          value={vitaminOptions.find((item) => item.value === undefined)}
          onChange={(value: any): void => {
            let newMyMedMap = {...myMedMap}
            let index = newMyMedMap.vitamins.findIndex((mmm) => mmm.id === value.value)
            if (index === -1) {
              let itemVitamin = vitaminOptions.find((item) => item.value === value.value)
              myMedMap.vitamins.push({
                id: itemVitamin.value,
                name: itemVitamin.label,
              })
              setMyMedMap({...newMyMedMap})
            }
          }}
          name={'vitamins'}
          isRequired={false}
        />
      </div>
    )
  }

  const renderDietTables = (): React.ReactNode => {
    let dietTableOptions: InputSelectOption[] = (medMap?.diet_tables || []).map((mm) => {
      return {
        value: mm.id,
        label: mm.name,
      }
    })
    let tagItems: React.ReactNode[] = []

    for (let i = 0; i < (myMedMap?.diet_tables || []).length; i++) {
      const dietTable = myMedMap?.diet_tables[i]
      tagItems.push(
        <Tag
          key={dietTable.id}
          tagText={dietTable.name}
          size={'xs'}
          color={'gray-300'}
          className={'mb-x4 mr-x2 ml-x2'}
          onClose={(): void => {
            let newMyMedMap = {...myMedMap}
            myMedMap.diet_tables.splice(i, 1)
            setMyMedMap({...newMyMedMap})
          }}
        />,
      )
    }

    return (
      <div className={'d-flex flex-column align-items-start'}>
        <p className={'sec-subtitle1 mb-x4'}>Диетические столы</p>
        <div
          className={
            'd-flex flex-row flex-wrap sec-subtitle2 ' + (tagItems?.length > 0 ? 'mb-0' : 'mb-x4')
          }>
          Выбранные: {tagItems?.length > 0 ? tagItems : 'пусто'}
        </div>
        <InputSelectVertical
          id={'diet_tables'}
          size={'sm'}
          options={dietTableOptions}
          label={'Диетические столы'}
          className={'mb-x6'}
          value={dietTableOptions.find((item) => item.value === undefined)}
          onChange={(value: any): void => {
            let newMyMedMap = {...myMedMap}
            let index = newMyMedMap.diet_tables.findIndex((mmm) => mmm.id === value.value)
            if (index === -1) {
              let itemDietTable = dietTableOptions.find((item) => item.value === value.value)
              myMedMap.diet_tables.push({
                id: itemDietTable.value,
                name: itemDietTable.label,
              })
              setMyMedMap({...newMyMedMap})
            }
          }}
          name={'diet_tables'}
          isRequired={false}
        />
      </div>
    )
  }

  const renderMedMap = (): React.ReactNode => {
    return (
      <div className={'d-flex flex-column align-items-start'}>
        {renderAllergen()}
        <Divider className={'mb-x6 w-100'} />
        {renderVitamins()}
        <Divider className={'mb-x6 w-100'} />
        {renderDietTables()}
        <Divider className={'mb-x6 w-100'} />
        <Button
          type={'button'}
          onClick={async (): Promise<void> => {
            await writeMed()
          }}
          size={'md'}
          className={'mb-0 mr-x2'}>
          Сохранить
        </Button>
      </div>
    )
  }

  if (user) {
    return (
      <div className={'profile-wrapper'}>
        <h1 className={'profile-header'}>Медицинские ограничения</h1>
        {renderMedMap()}
      </div>
    )
  } else {
    return <Loading />
  }
}

export default connectComponent(
  (state, props) => ({
    user: state.auth.user,
  }),
  (dispatch) => ({}),
  ProfileContainer,
)
